package com.lwj.service.administration;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lwj.constant.DepartmentType;
import com.lwj.dto.administration.DepartmentDto;
import com.lwj.dto.administration.DepartmentListDto;
import com.lwj.excel.TestExcel;
import com.lwj.exception.BusinessException;
import com.lwj.mapper.administration.DepartmentMapper;
import com.lwj.model.administration.Department;
import com.lwj.service.DozerService;
import com.lwj.vo.PageBean;
import com.lwj.vo.administration.DepartmentTreeVo;
import com.lwj.vo.administration.DepartmentVo;
import com.lwj.vo.system.DictionaryCategoryVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;

@Service("departmentService")
public class DepartmentServiceImpl implements DepartmentService {
    private static final Logger logger = LoggerFactory.getLogger(DepartmentServiceImpl.class);
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private DozerService dozerService;

    @Override
    public int deleteByPrimaryKey(String departmentId) {
        return departmentMapper.deleteByPrimaryKey(departmentId);
    }

    @Override
    public int insertSelective(Department record) {
        checkLevel(record);
        return departmentMapper.insertSelective(record);
    }

    @Override
    public Department selectByPrimaryKey(String departmentId) {
        return departmentMapper.selectByPrimaryKey(departmentId);
    }

    @Override
    public int updateByPrimaryKeySelective(Department record) {
        checkLevel(record);
        return departmentMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public PageBean<DepartmentVo> listDepartment( DepartmentListDto dto) {
        Department department = departmentMapper.selectByPrimaryKey(dto.getDepartmentId());
        dto.setPath(department.getPath());
        Page<DepartmentVo> objects = PageHelper.startPage(dto.getPageNumber(),dto.getPageSize());
        departmentMapper.listDepartment(dto);
        return PageBean.page(objects);
    }

    @Override
    public List<DepartmentTreeVo> listDepartmentTree(String departmentId, boolean excludeDisable) {
        return departmentMapper.listDepartmentTree(departmentId,excludeDisable);
    }

    @Override
    public List<DepartmentTreeVo>  departmentTree(String departmentId, boolean excludeDisable) {
        String path="1000";
        if(StringUtils.hasText(departmentId)){
            Department department = departmentMapper.selectByPrimaryKey(departmentId);
            path=department.getPath();
        }
        List<DepartmentTreeVo> departmentTreeVos = departmentMapper.listDepartmentTree(path, excludeDisable);
        return buildTree(departmentTreeVos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String   saveDepartment(DepartmentDto dto) {
        if(StringUtils.hasText(dto.getDepartmentId())){
            Department department = dozerService.map(dto, Department.class);
            beforeUpdate(department);
            updateByPrimaryKeySelective(department);
            return department.getDepartmentId();
        }else {
            Department department = dozerService.map(dto, Department.class);
            Integer level = DepartmentType.level(department.getType());
            department.setLevel(level);
            beforeInsert(department);
            insertSelective(department);
            return department.getDepartmentId();
        }
    }

    private void checkLevel( Department department ) {
        if(department.getLevel()==null){
            return;
        }
        String parentDepartmentId = department.getParentDepartmentId();
        Boolean check=true;
        if(StringUtils.isEmpty(parentDepartmentId)){
            check=department.getLevel()==1;
        }else {
            Department parent = selectByPrimaryKey(parentDepartmentId);
            Integer level = parent.getLevel();
            check=level<department.getLevel();
        }
        if(!check){
            throw new BusinessException("部门等级错误");
        }
    }

    public void beforeUpdate(Department department ){
        department.setStatus(null);
        department.setLevel(null);
        department.setPath(null);
        department.setSortNum(null);
        department.setParentDepartmentId(null);
    }
    public void beforeInsert(Department department ){
        department.setStatus("正常");
        String parentDepartmentId = department.getParentDepartmentId();
        //设置排序字段
        Integer integer = departmentMapper.selectMaxSort(parentDepartmentId);
        integer=integer==null?1000:integer+1;
        department.setSortNum(integer);
        if(StringUtils.hasText(parentDepartmentId)){
            Department parent = departmentMapper.selectByPrimaryKey(parentDepartmentId);
            department.setPath(parent.getPath()+"."+integer);
        }else {
            department.setLevel(1);
            department.setType(DepartmentType.ONE.getTypes()[0]);
            department.setParentDepartmentId("");
            department.setPath(integer+"");
        }
    }
    public List<DepartmentTreeVo>  buildTree(List<DepartmentTreeVo> departmentTreeVos){
        List<DepartmentTreeVo> result = new ArrayList<>(departmentTreeVos);
        departmentTreeVos.stream().forEach(a -> {
            departmentTreeVos.stream().forEach(b -> {
                if (a.getDepartmentId().equals(b.getParentDepartmentId())) {
                    a.addChildren(b);
                    result.remove(b);
                }
            });
        });
        return result;
    }

    @Async("asyncTaskExecutor")
    public Future< List<TestExcel>> data(int a, int b){
        logger.error("查询数据==="+new Date());
//        try {
//            Thread.sleep(3000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        PageHelper.startPage(a,b);
        List<DepartmentTreeVo> departmentTreeVos = departmentMapper.listDepartmentTree("1000", false);
        List<TestExcel> result=new ArrayList<>();
        for (int i = 0; i < departmentTreeVos.size(); i++) {
            DepartmentTreeVo departmentTreeVo = departmentTreeVos.get(i);
            TestExcel testExcel=new TestExcel();
            testExcel.setEmpId(departmentTreeVo.getDepartmentId());
            testExcel.setName(departmentTreeVo.getName());
            result.add(testExcel);
        }
        return  new AsyncResult(result) ;
    }
}
